"""
一、安装：
    1、安装python，配置环境变量
    2、cmd 下载 requests 库：镜像下载
        命令：pip install requests -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
二、注释：
    1、单行注释格式： # 注释内容 （不支持换行）
    2、多行注释格式：”“” 注释内容 “”“ （支持换行）
三、标识符：
    1、用来对变量，方法、类进行命名
    2、标识符命名规则：
        1）内容限定：使用中文、英文、数字、下划线_ 命名
        2）大小写敏感
        3）不可以与python关键字重名
        4)不可以使用数字开头
    3、标识符命名规范：
        1)  命名使用全小写
"""
# 字面量：固定在代码中的值
# 变量：存储的值可以发生改变
"""
一、 变量和数据类型
变量的格式：
    1、变量格式：变量名 = 变量值
    2、变量可以直接定义赋值，不需要声明变量的数据类型
    3、变量需要遵循标识符命名规范，需要严格区分大小写，避免和内置函数，保留字重名
    4、可以使用内置函数 type(变量名) 检测变量的数据类型  
数据类型：
    1、int：整数类型
    2、float：浮点数类型
    3、string：字符串类型
    4、bool：布尔类型，True（真），False（假），首字母大写
数据类型转换：
    1、int(x) : 将 数字字符串 x转换成 整数
    2、float(x) : 将x转换成 浮点数 
    3、str(x) : 将x转换成 字符串 
    4、repr(x) : 将x转换成 表达式字符串 
    5、eval(str) : 计算字符串中有效的python表达式，返回一个对象
    6、chr(x) : 将整数x 转换成 一个字符
    7、ord(x) : 将一个字符x 转换成 对应的整数
”“”
二、运算符
算术运算符：
    1、+ ：加（还可以运用于字符串之间的拼接，但字符串不能使用+号拼接其他数据类型）
    2、- ：减
    3、* ：乘
    4、/ ：除法
    5、// ：整除（取整数）
    6、% ：取余（取余数）
    7、** ：求平方
赋值运算符：
    1、= ： 标准赋值
    2、+=
    3、-=
    4、*= 
    5、/=
    6、//=
    7、**=
转义字符：(前后需要 \n xxx \n )
    1、\n : 换行符
    2、\r : 回车符
    3、\t : 水平制表符，相当于tab键（4个空格）
    4、\\ : 反斜杠
    5、\' : 单引号
    6、\" : 双引号

三、占位符
占位符：(百分号)
    1、字符串占位符格式： %s % 值
    2、整数占位符格式： %d % 值
    3、浮点数占位符格式： %f % 值
    4、多个变量展位符格式： %s %d %f % (值1,值2,值3)    
精度控制：
    1、使用m.n来控制变量的精度
    2、m表示变量的宽度（长度），比自身小则不生效，比自身大则补空位
    3、n表示小数点后的宽度（会进行四舍五入）
字符串格式--表达式的格式化：
    1、表达式的格式化： f"{表达式}"
    2、表达式：具有明确结果的代码语句

input函数：
    1、接收接盘输入的内容，默认都接收为字符串
    2、函数内可以添加提示语
print 函数：
    1、输出结果默认换行，可以使用end控制不换行：print("猫猫你好！",end = '')
len 函数：
    1、统计长度
四、判断语句和循环语句
比较运算符：
    1、==
    2、!=
    3、>
    4、<
    5、>=
    6、<=

判断语句 if elif else 格式： 
    if 条件1:
        条件成立时，执行的语句
    elif 条件2:
        执行语句
    else:
        执行语句

循环语句 while 循环：条件需要得到布尔类型，True表示继续循环，False表示结束循环
    while 条件:
        满足条件时执行语句

循环语句 for 循环 格式：
    for 临时变量 in 待处理数据集（序列）:
         循环满足条件时执行语句

    # range(num1, num2，num3)    // 获取一个从num1开始，到num2之间间隔num3的数字序列（不包含num2自身） 
    # range(num1, num2)    // 获取一个从num1开始，到num2之间的数字序列（不包含num2自身）
    # range（num）     // 获取一个从0开始到num之间的数字序列（不包含num自身）

循环断点和中断：
    1、break：退出循环
    2、continue：结束语句所在循环，进入下一次循环
五、函数
函数：
    1、函数是：封装好的，可重复使用的，用来实现特定功能的代码函数
    2、可使用函数：可以提高代码的复用性，减少重复性，提高效率
    3、使用 def 定义一个函数
函数格式：
    def 函数名(传参):
        函数说明文档
        函数体
        return 返回值   
函数传参：
    1、函数中定义的参数，称为形式参数（形参）
    2、函数中调用的参数，成为实际参数（实参）
    3、多个参数使用逗号隔开
    4、实参需要和形参一一对应
    5、可以使用 global定义函数内的变量为全局变量
函数返回值：
    1、 没有使用return返回值时，函数会默认返回”None“，为空的意思，数据类型是”NoneType“
    2、也可以使用return直接返回None
    3、None在if语句中等同于False
函数说明文档：
    三个双引号
    :param 参数: 
    三个双引号
六、
数据容器：
    1、数据容器：一种可以存储多个元素的python数据类型
    2、数据容器包含：列表（list）、元组（tuple）、字符串（str）、集合（set）、字典（dict ）
列表（list）：定义后允许被修改
    1、字面量格式： [元素1,元素2,.....]
    2、变量格式： 变量 = [元素1,元素2,.....]
    3、定义空列表： 变量 = []  或者 变量 = lsit()
    4、列表内可以嵌套列表
    5、元素类型：数据类型没有限制
    6、列表的下标索引：（从左到右）正序从0开始递增，（从右到左）反序从-1开始递减
    7、列表常用方法：
        （1）查询：列表名称.index(元素)   // 查询元素在列表中所在的下标索引值，若不存在会报错，若存在则返回所在索引值
        （2）修改：列表名称.[n] = 元素    // 修改列表下标索引为n的元素内容
        （3）插入：
                列表名称.insert(下标索引, 元素)    //在指定下标位置插入新元素
                列表名称.append("素)      // 在列表尾部追加整个元素
                列表名称.extend(元素)      //在列表尾部逐个添加元素内容
        （4）删除：
                del 列表名称[n]     // 删除下标索引为n的元素
                列表名称.pop(n)     // 取出（删除）下标索引为n的元素，取出䣌元素可以作为返回值
                列表名称.remove(元素)    // 将列表中匹配到的”元素内容“删除
        （5）清空：列表名称.clear()      // 清空列表的元素，变成一个空列表
        （6）统计：
                列表名称.count(元素)    //统计某个元素在列表的数量
                len(列表名称)     // 统计列表的长度，内置函数
    8、循环遍历列表
        （1）while循环列表：自定义循环变量
        （2）for循环列表：不可以自定义变量，只能从数据容器里面取出元素

元组（tuple）：定义后不允许被修改，但可以修改嵌套的列表
    1、字面量格式： (元素1, 元素2,.....)
    2、变量格式： 变量 = (元素1, 元素2,.....)
    3、定义空元组： 变量 = ()  或者 变量 = tuple()
    4、定义单个元素的元组：变量 = (元素1,)     // 需要用逗号结尾
    5、元组内可以嵌套列表、元组
    6、元素类型：数据类型没有限制
    7、元组的下标索引：（从左到右）正序从0开始递增，（从右到左）反序从-1开始递减
    8、元组常用方法：
        （1）查询：元组.index(元素)      // 查询元素在元组中下标值
        （2）统计：
                元组.count(元素)      //统 计某个元素在元组中的个数
                len(元组)         // 统计元组的长度
    9、循环遍历列表
        （1）while循环列表：自定义循环变量
        （2）for循环列表：不可以自定义变量，只能从数据容器里面取出元素

字符串：定义后不允许修改
    1、字面量格式： "字符串" 或者 '字符串'
    2、变量格式： 变量 = ("字符串") 或者 ('字符串')
    3、元素类型：数据类型没有限制
    4、字符串的下标索引：（从左到右）正序从0开始递增，（从右到左）反序从-1开始递减
    5、字符串常用方法：
        （1）查询：字符串.index(元素)      // 查询元素在元组中下标值
        （2）替换：字符串.replace(字符串1, 字符串2)      // 将字符串1替换成字符串2
        （3）分割：字符串.split(字符串1)     // 按照给定字符串进行分割，分割出来的字符串组成一个新的列表，返回列表
        （4）去除：字符串.strip(字符串1)     // 去除字符串首尾中的‘字符串1’，未传值时默认去除首尾的空格或换行符,返回新的字符串
        （5）统计：
                字符串.count(元素)      //统 计某个元素在元组中的个数
                len(字符串)         // 统计元组的长度
    6、循环遍历列表
        （1）while循环列表：自定义循环变量
        （2）for循环列表：不可以自定义变量，只能从数据容器里面取出元素
序列:
    1、序列定义：内容连续、有序、支持下标索引的一类数据容器
    2、序列包含哪些数据容器：列表（list）、元组（tuple）、字符串（str）
    3、序列切片格式：序列[起始下标位置:结束下标位置:步长]
        （1）起始下标位置可以省略，省略不写则从0开始
        （2）结束下标位置可以省略，省略不写则从末尾开始，写n的话则不包含n位置的值
        （3）步长可以省略，省略不写则默认为1（步长可以写负数，表示倒序执行），步长为n，则每次跳过n-1个元素取
        （4）序列切片后是得到一个新的序列，不会改变原序列   

集合（set）：定义后允许修改
    1、字面量格式： {元素,元素,元素,.....}     // 大括号
    2、变量格式： 变量 = {元素,元素,元素,.....}
    3、定义空集合： 变量 = set()
    4、元素类型：数据类型没有限制
    5、元素是否允许重复：不允许重复数据存在
    6、集合中存储的数据是无序的，不支持下标索引
    7、集合常用方法：
        （1）新增：集合.add(元素)      // 在集合内添加一个元素（修改原集合）
        （2）移除：集合.remove(元素)      // 移除集合中指定元素（修改原集合）
        （3）取出：集合.pop（）     //  从集合中随机取出一个元素，得到返回值，（修改原集合）
        （4）清除：集合.clear()     // 清空集合内容
        （5）差集：集合1.difference(集合2)    // 返回集合1和集合2中不同的元素，得到新集合，原集合均不变，
        （6）消除差集：集合1.difference_update(集合2)     // 删除集合1中集合2有的元素，修改集合1
        （7）合集：集合1.union(集合2)        // 返回集合1合集合中的元素，得到一个新的集合，原集合1，2不变
        （8）len(集合)         // 统计集合的长度
    8、支付for循环，不支持while循环
        for element in 集合：

字典（dict）：
    1、字面量格式： {key:value, key:value,....}     // 大括号 和 键值对
    2、变量格式： 变量 = {key:value, key:value,....}
    3、定义空字典： 变量 = dict()   或者 {}
    4、key数据类型：数据类型没有限制，但不能为字典
    5、value数据类型：数据类型没有限制，可以为字典
    6、key是否允许重复：不允许重复key存在，若重复存在，后面key的数据会覆盖前面key的数据
    7、字典中存储的数据是无序的，不支持下标索引，通过key检索value
    8、通过dict[key]访问key对应的value
    7、字典常用方法：
        （1）新增/修改：字典[key] = value      // 若key存在字典中则为修改，若不存在则为新增
        （2）获取key对应的值：字典[key]      // 获取字典中，key对应的value
        （3）取出value删除key：字典.pop（key）     //  取出key对应的值，并且删除字典中的key
        （4）清除：字典.clear()     // 清空字典内容
        （5）获取字典全部的key：字典.keys()   // 获取字典中所有的key
        （6）统计：len(字典)         // 统计字典的长度
    8、支付for循环，不支持while循环
        (1) for my_keys in dict：
                dict[my_keys]    // 循环取key对应的值
        (2) num_keys = dict.keys()
            for keys in num_keys:    // 循环取key对应的值
                dict[keys]

数据容器总结：
    1、是否支持下标索引进行分类：
        （1）支持：列表（list）、元组（tuple）、字符串（str）---均为序列类型
        （2）不支持：集合（set）、字典（dict）---非序列类型
    2、是否支持重复元素：
        （1）支持：列表（list）、元组（tuple）、字符串（str）---均为序列类型
        （2）不支持：集合（set）、字典（dict）---非序列类型
    3、是否支持修改：
        （1）支付：列表（list）、集合（set）、字典（dict）
        （2）不支持：元组（tuple）、字符串（str）
    4、是否是有序:
        （1）有序：列表（list）、元组（tuple）、字符串（str）
        （2）无序：集合（set）、字典（dict）

数据容器特点总结：
    （1）列表（list）：数据可修改、可重复
    （2）元组（tuple）：数据不可修改、可重复
    （3）字符串（str）：数据不可修改、可重复
    （4）集合（set）：数据可修改、不可重复
    （5）字典（dict）：数据可修改、不可重复

数据容器通用方法：
    1、通用for循环
    2、max()：返回容器中最大的元素
    3、min()：返回容器中最小的元素
    4、len()：统计容器中元素的数量
    5、list()：将数据容器转化成列表
    6、tuple()：将数据容器转化成元组
    7、str()：将数据容器转化成字符串
    8、set()：将数据容器转化成集合
    9、sorted(序列, reverse=True)： 将序列进行排序，revers=True代表降序排序，revers=False代表升序排序

七、
函数多返回值：
    1、语法格式：
        def test_return:
            return value1,value2,value3     # 逗号隔开多个返回值
        a,b,c = test_return()      # 接收多个返回值

函数参数：
    1、位置传参：def fun(k1, k2, k3):
    2、关键字传参：def fun(k1=value1, k2=value2)    //键值对
    3、缺省传参：def fun(k1=1)      //默认值，多个参数时缺省参数需放最后
    4、不定长传参：
        （1）位置不定长：def fun(*args)    // 接收参数个数不限制，接收到的参数以元组形式存储
        （2）关键字不定长：def fun(**kwargs)      //多个参数按照key=value形式传入，接收到的参数以字典形式存储

匿名函数：
    1、函数作为参数：将一个函数A作为另一个函数B的参数传入，在函数B体内调用函数A
    2、匿名函数定义：使用 lambda 关键字进行定义
    3、匿名函数格式：
        lambda 传参: 函数体   // 只支持一行代码
    4、匿名函数使用注意事项：
        （1）匿名函数用于临时构建一个函数，只用一次的场景
        （2）匿名函数中只能写一行代码，若要写多行则使用def定义函数

八、文件
文件编码：
    1、文件编码：是一个规则集合，记录内容和二进制间进行相互交互的逻辑
    2、常用文件编码：UTF-8
    3、为何使用编码：因计算机只认识0和1，需要将内容编译成0和1才能存储在计算机种
文件打开：
    1、使用open函数打开一个文件，返回一个文件对象，若以只读方式打开不存在文件会报错，若以写入方式打开不存在文件，会自动创建一个文件
    2、语法格式1：
        f = open(name, mode, encoding)
        // f 接收返回的文件对象
        // name是要打开的文件名称（包含路径）
        // mode是访问模式（只读、写入、追加）
        // encoding是编码格式，一般值都为UTF-8
    3、mode：文件访问模式
        （1）r ：只读模式，只能读取文件内容，该模式下打开不存在文件会报错
        （2）w ：写入模式，可以向文件内写入内容，该模式下打开不存在文件会创建新文件，写入时会覆盖文件原有内容
        （3）a ：追加模式，在文件最后追加新内容，该模式下打开不存在文件会创建新文件，写入时是在文件末尾追加内容
文件对象读取时常用方法：
    1、读取文件中前num个字符： f.read(num)     // 不写num默认读取全部内容
    2、每次读取一行： f.readline()
    3、将文件按照行数以列表形式读取出来，得到一个列表数据： f.readlines()
    4、关闭文件： f.close()
    5、自动关闭文件： 
        with open(name,mode,encoding) as f:
            文件操作内容
    6、for循环，逐行读取文件： 
        for line in f:
            逐行读取文件的内容
文件对象写入时常用方法：
    1、向文件对象写入内容：f.write()        // ，存入缓存中，会将文件中的原有的内容覆盖
    2、将缓存中写入的内容写进文件中：f.flush()     
    3、关闭文件：f.close()         //close内置了flush的功能，写了colse可以不用写flush

九、
异常：
    1、影响程序运行的异常，也就是bug                          
    2、捕获异常的格式：
        try:
            xxx  //有可能出现异常的代码
        except:      // 捕获所有异常
        except Exception as e:     // 捕获所有异常（常用）
        except 异常名称 as e:      // 捕获指定异常
        except (异常名称1,异常名称2) as e:     //捕获多个指定异常
            xxxx    //捕获到异常后执行的代码
        else
            xxxxx     // 未捕获到异常时执行的代码
        finally:
            xxxx       // 无论是否有异常都有执行的代码，一般用来关闭占用的资源
    3、异常的传递性： 异常具有传递性

python模块：
    1、导入python内置文件或插件的功能
    2、语法格式：
        （1）import 文件名/模块名             // 引入整个模块，通过 模块. 可以访问模块内的类/变量/方法/功能
        （2）import 文件名/模块名 as 别名     // 引入整个模块，通过 别名. 可以访问模块内的类/变量/方法/功能
        （3）from 文件名/模块名 import *      // 引入整个模块的类/变量/方法/功能，可以直接访问模块内的类/变量/方法/功能
        （4）from 文件名/模块名 import 类/变量/方法/功能名    // 引入模块的类/变量/方法/功能，可以直接访问模块内的类/变量/方法/功能
        （5）from 文件名/模块名 import 类/变量/方法/功能名 as 别名     // 引入模块的类/变量/方法/功能，可以直接使用别名访问模块内的类/变量/方法/功能
    （3）一般from 可以省略，直接import引入，as也可以省略
自定义模块：
    1、新建python文件：文件名.py
    2、将自定义的变量，函数，方法，类，写在自定义文件中
    3、通过import引入自定义文件
    4、自定义文件内的 __main__ 变量功能：  使代码只在自身文件中执行，被导入时不会执行
        if __name__ == "__main__":    // 只在自定义文件内执行的语句，若外部引用该文件时，不会执行if判断下的语句
            执行语句          
    5、自定义文件内的 __all__ 变量功能：  限制import * 时可以导入的功能
        __all__ = [功能1，功能2]       // 外部导入自定义模块时，使用*导入时只能导入__all__变量列表内的功能

python包：
    1、由多个模块文件 + __init__.py 文件组成的python包，可以将多个模块归为一类，方便使用
    2、创建包的流程：项目右键---新建---python软件包       // 创建成功会自动创建__init__.py文件
    3、可以将__all__变量写在__init__.py文件中，来控制导入的功能

Json模块：
    1、Json 是一个轻量级的数据交互格式，采用完全独立于编程语言的文本格式来存储和表示数据，是字符串格式的数据
        （1）在python中使用 import json 导入json模块
    2、Json 是一个单独的字典 或者 内部元素为字典的列表 的字符串
        （1）字典："{"猫猫":18, "菜菜":20, "格格":17}"
        （2）列表内嵌字典："[{"猫猫":18, "菜菜":20, "格格":17},{"花花":18, "尖尖":20, "狗狗":17}]"
    3、python语言使用Json有很大的优势，可以无缝转化
        （1）字典：{"猫猫":18, "菜菜":20, "格格":17}
        （2）列表内嵌字典：[{"猫猫":18, "菜菜":20, "格格":17},{"花花":18, "尖尖":20, "狗狗":17}]
    4、Json格式数据转化：
        （1）将Python数据转化成Json数据：json_data = json.dumps(py_data)
        （2）将带有中文的Python数据转换成Json数据： json_data = json.dumps(py_data,ensure_ascii=False)
        （3）将Json的数据转化成Python数据：py_data = json.loads(json_data)

pyecharts模块：
    1、可视化图表技术栈 echarts框架的python版本是：PyEcharts
    2、如何安装PyEcharts： pip install pyecharts
        进入 cmd ---> 输入 pip install pyecharts 回车---> 输入 python 回车，进入python---> 输入 import pyecharts 回车，没有问题记导入成功
    3、官方文档：https://gallery.pyecharts.org/#/README
               https://pyecharts.org/#/zh-cn/global_options

十、
类与对象
    1、类的定义：
        class 类名:
            类的属性,      // 类的属性称为 成员变量
            类的行为       // 类的行为称为 成员方法
            def 方法名(self)：    //在定义类的方法时，self是比传，它代表的是这个类对象本身（跟this一样）   
    
    2、创建类的对象：
        变量名 = 类名()
                
    3、注意：方法是定义在类里面的，而函数是定义在类外面的
    4、定义成员方法是必须要传self
    5、成员方法在调用成员属性时，必须使用 self.类的属性名 调用
    6、构造函数定义：
        def __init__(self):
    7、构造函数在构建类对象时会自动执行
    8、创建类型对象时可以传参，参数会传递给构造函数，可以给成员变量赋值，同时也可以定义成员变量
    9、常见内置方法（魔术方法）：
        1） def __init__(self)     # 构造方法
        2） def __str__(self)      # 将类对象转换字符串
        3） def __lt__(self)       # 用于2个类对象之间进行小于/大于比较（实际是小于） 
        4） def __le__(self)       # 用于2个类对象之间进行小于等于/大于等于比较
        5） def __eq__(self)       # 用于2个类对象之间进行相等比较
"""